/*
Copyright 2008  Four Roads LLC conact@4-roads.com

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either 
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with this library.  If not, see <http://www.gnu.org/licenses/>.
*/
 
using System;
using System.Text;
using System.Web.UI;
using CommunityServer.Components;
using CA = ComponentArt.Web.UI;
using ResourceManager = FourRoads.Links.Controls.ResourceManager;
using CommunityServer.ControlPanel.UI;

namespace FourRoads.Links.Controls
{
	/// <summary>
	/// Summary description for BaseControl.
	/// </summary>
	public class BaseGridControl : UserControl
	{
		public BaseGridControl()
		{

		}

		# region CA Grid Preferences

		/// <summary>
		/// Users option to have Grid Groups Expanded by default, Will return default values before the OnLoad event
		/// Due to dependancy on CSConect.Current.User
		/// </summary>
		public bool ExpandGrouping
		{
			get{return Globals.SafeBool(this.PanelPage.CurrentUser.GetExtendedAttribute("CPExpandGroups"),true);}
		}

		/// <summary>
		/// Users option to allow CA Grid Grouping where enabled, Will return default values before the OnLoad event
		/// Due to dependancy on CSConect.Current.User
		/// </summary>
		public bool EnableGrouping
		{
			get{return Globals.SafeBool(this.PanelPage.CurrentUser.GetExtendedAttribute("CPEnableGroups"),false);}
		}
		
		private string enableSearchBox = null;
		/// <summary>
		/// Users option to allow CA Grid SearchBox where enabled, Will return default values before the OnLoad event
		/// Due to dependancy on CSConect.Current.User (can be overridden on the init section of the page / control)
		/// </summary>
		public bool EnableSearchBox
		{
			get{return Globals.SafeBool(enableSearchBox,Globals.SafeBool(this.PanelPage.CurrentUser.GetExtendedAttribute("CPEnableSearchBox"),false));}
			set{enableSearchBox = value.ToString();}
		}
 
		/// <summary>
		/// Users option to force Client Mode, Callback Mode or auto...  Where auto is defined as less than 500 items = client
		/// Auto will default to Client and requires the developer to set Callback if required.  This value gets bound on ApplyUserSettings
		/// and can be overridden there if required.
		/// </summary>
		private CA.GridRunningMode gridMode = CA.GridRunningMode.Client;
		public CA.GridRunningMode GridMode
		{
			get
			{
				if(this.PanelPage.CurrentUser.GetExtendedAttribute("CPGridMode") != null && 
					CA.GridRunningMode.IsDefined(typeof(CA.GridRunningMode), this.PanelPage.CurrentUser.GetExtendedAttribute("CPGridMode")))
					return (CA.GridRunningMode)CA.GridRunningMode.Parse(typeof(CA.GridRunningMode),this.PanelPage.CurrentUser.GetExtendedAttribute("CPGridMode"));
				else
					return gridMode;
			}
			set
			{
				if(!CA.GridRunningMode.IsDefined(typeof(CA.GridRunningMode), this.PanelPage.CurrentUser.GetExtendedAttribute("CPGridMode")))
				{
					gridMode = value;
					if(Grid != null)
						Grid.RunningMode = value;
				}
			}
		}

		/// <summary>
		/// This switch toggles between a pager in the footer and a scollbar in the grid
		/// </summary>
		private bool showScrollBar = false;
		public bool ShowScrollBar
		{
			get{return showScrollBar;}
			set{showScrollBar = value;}
		}

		/// <summary>
		/// The users prefered Grid Page Size, Will return default values before the OnLoad event
		/// Due to dependancy on CSConect.Current.User
		/// </summary>
		public int DefaultPageSize
		{
			get
			{
				if(this.DefaultScalePageSize)
					return Globals.SafeInt(this.PanelPage.CurrentUser.GetExtendedAttribute("CPPageSize"),10) / CurrentGridRowSize;
				else
					return Globals.SafeInt(this.PanelPage.CurrentUser.GetExtendedAttribute("CPPageSize"),10);

			}
		}

		/// <summary>
		/// Hide the whole heading row of CA Grids if neither grouping or searching are enabled, 
		/// Will return default values before the OnLoad event
		/// Due to dependancy on CSConect.Current.User
		/// </summary>
		public bool ShowHeading
		{
			get
			{
				if (EnableGrouping == false && EnableSearchBox == false)
					return false;
				else
					return true;
			}
		}

		/// <summary>
		/// The users option to allow the developer to scale the page size for multi row grids, 
		/// Will return default values before the OnLoad event
		/// Due to dependancy on CSConect.Current.User
		/// </summary>
		public bool DefaultScalePageSize
		{
			//The scale page size allows page designers to set how many rows a normal grid row will take to render, and 
			//should allow for more consistant grid rendering sizes (This proprty has been disabled by default to prevent confusion)
			get{return Globals.SafeBool(this.PanelPage.CurrentUser.GetExtendedAttribute("CPPageSizeScale"),false);}
		}

		/// <summary>
		/// The number of records in the grid.  You need to set this value if running in callback mode where setting the grid
		/// Dataset to a subset of the records.  If the dataset contains all records you dont need to manually set this.
		/// </summary>
		private int recordCount = 0;
		public int RecordCount
		{
			get
			{
				if(Grid != null)
					return (recordCount > Grid.RecordCount) ? recordCount : Grid.RecordCount;
				else
					return recordCount;
			}
			set
			{
				recordCount = value;
				if(Grid != null)
					Grid.RecordCount = value;
			}
		}

		private int currentGridRowSize = 1;
		/// <summary>
		/// A setting which can be changed from the default on a page to allow the developer to 
		/// Limit the number of row returned if they are larger than standard single line rows 
		/// Will return default values before the OnLoad event
		/// Due to dependancy on CSConect.Current.User
		/// </summary>
		public int CurrentGridRowSize
		{
			get{return currentGridRowSize;}
			set
			{
				currentGridRowSize = value;
				if(Grid != null)
					Grid.PageSize = this.DefaultPageSize;
			}
		}

		#endregion

		/// <summary>
		/// Override this function to put content in the grid.
		/// Be sure to call base after you bind data to the grid or call ApplyUserSettings()
		/// </summary>
		protected virtual void buildGrid()
		{
			this.ApplyUserSettings();
		}

		protected PanelPage PanelPage
		{
			get { return Page as PanelPage;}
		}

		protected CA.Grid Grid = null;

		protected override void CreateChildControls()
		{
			Grid = (CA.Grid)FindControl("Grid1");

			base.CreateChildControls ();
		}

		/// <summary>
		/// This method configures the main grid properties tipically you would override ConfigureGrid
		/// To add page specific functionality
		/// </summary>
		protected virtual void ConfigureBasicGrid()
		{
			ConfigureGridProperties();
			ConfigureGridLevelProperties();
			ConfigureGridColumnProperties();
			AddGridLoadingTemplate();
		}

		/// <summary>
		/// Override this to add page specific formatting to your grid
		/// </summary>
		protected virtual void ConfigureGrid(){}

		protected override void OnPreRender(EventArgs e)
		{
			base.OnPreRender (e);

//			Page.RegisterStartupScript(this.ClientID, string.Format(@"<script language=""javascript"">
//	window.{0}_OldOnResize = window.onresize;
//	window.onresize = new Function ('window.{0}.Render(); if (window.{0}_OldOnResize) {{ window.{0}_OldOnResize(); }}');
//</script>", Grid.ClientObjectId));
		}


		protected override void Render(HtmlTextWriter writer)
		{
			Grid.RecordCount = RecordCount;

			if(!this.ShowScrollBar)
			{
				if(this.GridMode == CA.GridRunningMode.Client)
				{
					Grid.SliderPopupClientTemplateId = "SliderTemplate"; 
					Grid.SliderPopupOffsetX = 20; 
				}
				else
				{
					Grid.SliderPopupClientTemplateId = null; 
					Grid.SliderPopupOffsetX = 72; 
				}
			}
			base.Render (writer);
		}


		public virtual void OnNeedDataSource(object sender, EventArgs e)
		{
			buildGrid();
		}

		public virtual void OnNeedRebind(object sender, EventArgs e)
		{
			Grid.DataBind();
			Grid.RecordCount = this.RecordCount;
		}

		public virtual void OnPageChanged(object sender, CA.GridPageIndexChangedEventArgs e)
		{
			Grid.CurrentPageIndex = e.NewIndex;
		}

		public virtual void OnFilter(object sender, CA.GridFilterCommandEventArgs e)
		{
			Grid.Filter = e.FilterExpression;
		}

		public virtual void OnSort(object sender, CA.GridSortCommandEventArgs e)
		{
			Grid.Sort = e.SortExpression;
		}

		public virtual void OnGroup(object sender, CA.GridGroupCommandEventArgs e)
		{
			Grid.GroupBy = e.GroupExpression;
		}

		override protected void OnInit(EventArgs e)
		{
			base.OnInit(e);
			
			EnsureChildControls();
			
			ConfigureBasicGrid();
			ConfigureGrid();

			this.Grid.NeedDataSource += new CA.Grid.NeedDataSourceEventHandler(this.OnNeedDataSource);
			this.Grid.GroupCommand += new CA.Grid.GroupCommandEventHandler(this.OnGroup);
			this.Grid.FilterCommand += new CA.Grid.FilterCommandEventHandler(this.OnFilter);
			this.Grid.PageIndexChanged += new CA.Grid.PageIndexChangedEventHandler(this.OnPageChanged);
			this.Grid.SortCommand += new CA.Grid.SortCommandEventHandler(this.OnSort);
			this.Grid.NeedRebind += new CA.Grid.NeedRebindEventHandler(this.OnNeedRebind);
		}

		#region GridHelpers

		/// <summary>
		/// Adds the standard properties to the base CA Grid.  The minimum required in the control is now
		/// id, runat, and Width.  If editing is necessary, AllowEditing, EditOnClickSelectedItem,
		/// AutoCallBackOn, and ClientSideOn properties and JS should be inclided manually
		/// </summary>
		protected virtual void ConfigureGridProperties()
		{
			Grid.CssClass="Grid"; 

			if(this.EnableSearchBox )
			{
				Grid.SearchTextCssClass="GridHeaderText"; 
				Grid.SearchOnKeyPress=true; 
			}
			Grid.HeaderCssClass="GridHeader"; 
			Grid.FooterCssClass="GridFooter";
			if(!this.ShowScrollBar)
			{
				Grid.PagerTextCssClass="GridFooterText"; 
				Grid.PagerButtonWidth=41; 
				Grid.PagerButtonHeight=22; 
				Grid.PagerImagesFolderUrl= string.Format("{0}images/caimages/pager",  SiteUrls.Instance().Locations["ControlPanel"]); 
			}
			else
				ConfigureScrollBarProperties();

			Grid.ImagesBaseUrl= string.Format("{0}images/caimages",  SiteUrls.Instance().Locations["ControlPanel"]); 
			Grid.EditOnClickSelectedItem = false;
			Grid.ManualPaging = false;

			Grid.RunningMode = GridMode;
			Grid.PageSize = this.DefaultPageSize;

			//This prevents the grid cols from shrinking too far if one col contains too much data
			//Grid.FillContainer = true;
			//Commenting out the previous line causes the grids to resize to the window appropriately now
		}

		/// <summary>
		/// Used to setup a scrollbar for the grid instead of a pager
		/// </summary>
		protected virtual void ConfigureScrollBarProperties()
		{
			Grid.ShowFooter = false;
			Grid.ScrollBar= CA.GridScrollBarMode.Auto;
			Grid.ScrollTopBottomImagesEnabled= true;
			Grid.ScrollTopBottomImageHeight= 2;
			Grid.ScrollTopBottomImageWidth= 16;
			Grid.ScrollImagesFolderUrl= string.Format("{0}images/caimages/scroller",  SiteUrls.Instance().Locations["ControlPanel"]); 
			Grid.ScrollButtonWidth= 16;
			Grid.ScrollButtonHeight=17;
			Grid.ScrollBarCssClass="ScrollBar";
			Grid.ScrollGripCssClass="ScrollGrip";
			Grid.ScrollBarWidth=16;

			//Grid.ScrollPopupClientTemplateId="ScrollPopupTemplate"; 
		}

		/// <summary>
		/// Set the default CS properties on the Level[0] Grid element.
		/// Only the DataKeyField should be provided manually.
		/// </summary>
		protected virtual void ConfigureGridLevelProperties()
		{
			CA.GridLevel l = Grid.Levels[0];
			
			l.ShowTableHeading = false;
			l.ShowSelectorCells = false;
			l.RowCssClass = "Row";
			l.ColumnReorderIndicatorImageUrl = "";
			l.DataCellCssClass = "DataCell";
			l.HeadingCellCssClass = "HeadingCell";
			l.HeadingCellHoverCssClass = "HeadingCellHover";
			l.HeadingCellActiveCssClass = "HeadingCellActive";
			l.HeadingRowCssClass = "HeadingRow";
			l.HeadingTextCssClass = "HeadingCellText";
			l.SelectedRowCssClass = "SelectedRow";
			l.GroupHeadingCssClass="GroupHeading"; 
			l.SortAscendingImageUrl="asc.gif"; 
			l.SortDescendingImageUrl="desc.gif";
			l.SortImageWidth = 10; 
			l.SortImageHeight = 19; 
			l.EditCellCssClass="EditDataCell"; 
			l.EditFieldCssClass="EditDataField";
			l.EditCommandClientTemplateId="EditCommandTemplate"; 
			l.InsertCommandClientTemplateId="InsertCommandTemplate"; 
			l.AlternatingRowCssClass="AlternatingRow";

		}

		/// <summary>
		/// Auto binds the appropriate styles to rows (except the last row, which must be set manually)
		/// Also replaces any ResourceManager.[Resource Manager Key] values in the HeadingText with the 
		/// appropriate resource text.
		/// </summary>
		protected virtual void ConfigureGridColumnProperties()
		{

			Grid.Levels[0].Columns[0].HeadingCellCssClass = "FirstHeadingCell";
			Grid.Levels[0].Columns[0].DataCellCssClass = "FirstDataCell";

			foreach(CA.GridColumn gc in Grid.Levels[0].Columns)
			{
				if(gc.Visible)
				{
					gc.SortedDataCellCssClass = "SortedDataCell";
					//Allows for mock resource manager calls in heading text
					//eg HeadingText="ResourceManager.CP_Photos_GridCol_Name"
					if(gc.HeadingText.StartsWith("ResourceManager."))
						gc.HeadingText = ResourceManager.GetString(gc.HeadingText.Replace("ResourceManager.",""));

					//gc.TextWrap=true;
			
				}
			}
		}

		/// <summary>
		/// Adds a standard Loading template to the grid
		/// </summary>
		protected virtual void AddGridLoadingTemplate()
		{
			CA.ClientTemplate loadingTemplate = new CA.ClientTemplate();
			loadingTemplate.ID = "Loading";
			loadingTemplate.Text = string.Concat(@"
									<table cellspacing=""0"" cellpadding=""0"" border=""0"">
										<tr>
											<td style=""font-size:10px;"">Loading...&nbsp;</td>
											<td><img src=""", SiteUrls.Instance().LoadingImageUrl , @""" width=""16"" height=""16"" border=""0""></td>
										</tr>
									</table>") ;
			Grid.ClientTemplates.Add(loadingTemplate);
			Grid.LoadingPanelClientTemplateId = loadingTemplate.ID;
			Grid.LoadingPanelPosition = CA.GridRelativePosition.MiddleCenter;

		}

		/// <summary>
		/// Adds the standard published date template to the grid and binds it to the DateDataField column
		/// </summary>
		/// <param name="AuthorURL"></param>
		/// <param name="AuthorDataField"></param>
		/// <param name="DateDataField"></param>
		protected virtual void AddGridPublishedDateTemplate(string AuthorURL, string AuthorDataField, string DateDataField)
		{
			CA.ClientTemplate template = new CA.ClientTemplate();
			template.ID = String.Concat(DateDataField,"DateTemplate");
			template.Text = String.Format(@"
									<table width=""100%"" cellspacing=""0"" cellpadding=""1"" border=""0"">
										<tr>
											<td class=""CellText"" align=""right""> by: <a style=""color:#595959;"" href='## DataItem.GetMember(""{0}"").Value ##'><b>## DataItem.GetMember(""{1}"").Value ##</b></a></td>
										</tr>
										<tr>
											<td class=""CellText"" align=""right""><font color=""#595959"">## DataItem.GetMember(""{2}"").Value ##</font></td>
										</tr>
									</table>", AuthorURL, AuthorDataField, DateDataField);

			Grid.ClientTemplates.Add(template);

			AttachGridColumnClientTemplate(DateDataField, template);

		}

		/// <summary>
		/// Adds a standard Cross / Check Template and binds it to a boolean column in the grid
		/// </summary>
		/// <param name="DataFieldName"></param>
		protected virtual void AddGridCheckMarkTemplate(string DataFieldName)
		{
			CA.ClientTemplate template = new CA.ClientTemplate();
			template.ID = string.Concat("CheckTemplate",DataFieldName) ;
			template.Text = String.Format(@"<img src=""{0}images/## DataItem.GetMember(""{1}"").Value ##.gif"" width=""16"" height=""15"" />", SiteUrls.Instance().Locations["ControlPanel"], DataFieldName);
			
			Grid.ClientTemplates.Add(template);

			CA.GridColumn gc = AttachGridColumnClientTemplate(DataFieldName, template);
			
			//if the DataFieldName was not found this will throw an error
			gc.Width = 65;
			gc.FixedWidth = true;
			gc.Align = CA.TextAlign.Center;
		}

		/// <summary>
		/// Adds an HREF Template to the grid and binds it to the specified column
		/// To support advanced client side databinding, the ## DataItem.GetMember("DataFieldName").Text ##
		/// syntax can be used in the href
		/// </summary>
		/// <param name="Href"></param>
		/// <param name="DataFieldName"></param>
		protected virtual void AddGridHrefTemplate(string Href, string DataFieldName)
		{
			AddGridHrefTemplate(Href, "", DataFieldName);
		}
		protected virtual void AddGridHrefTemplate(string Href, string cssClass, string DataFieldName)
		{
			AddGridHrefTemplate(Href, cssClass, DataFieldName, "");
		}
		protected virtual void AddGridHrefTemplate(string Href, string cssClass, string DataFieldName, string SecondLine)
		{
			CA.ClientTemplate template = new CA.ClientTemplate();
			template.ID = string.Concat("HrefTemplate", DataFieldName);

			string style = "";
			if(!Globals.IsNullorEmpty(cssClass))
				style = string.Concat("class=", cssClass); 
			template.Text = String.Format(@"<a href='{0}' {1}>## DataItem.GetMember(""{2}"").Value ##</a>", Href, style, DataFieldName);

			if(!Globals.IsNullorEmpty(SecondLine))
				template.Text = String.Concat(template.Text, "<br />", SecondLine);

			Grid.ClientTemplates.Add(template);
			
			AttachGridColumnClientTemplate(DataFieldName, template);
		}

		/// <summary>
		/// Adds multiple HREF Templates to the grid and binds them to the specified columns.
		/// Links will be seperated by a specified delimter.
		/// To support advanced client side databinding, the ## DataItem.GetMember("DataFieldName").Text ##
		/// syntax can be used in the href
		/// </summary>
		protected virtual void AddGridHrefTemplate(string[] href, string[] label, string dataFieldToAttach, string delimiter)
		{
			 AddGridHrefTemplate(href, label, new string[href.Length], dataFieldToAttach, delimiter);
		}
		protected virtual void AddGridHrefTemplate(string[] href, string[] label, string[] cssClass, string dataFieldToAttach, string delimiter)
		{
			if (href.Length != label.Length)
				throw new Exception("Parameter array lengths do not match!");

			int lowerBound = href.GetLowerBound(0);

			CA.ClientTemplate template = new CA.ClientTemplate();
			template.ID = string.Concat("HrefTemplate", label[lowerBound]);
			template.Text = "";

			for (int i = lowerBound; i <= href.GetUpperBound(0); i++)
			{
				if (i != lowerBound)
					template.Text += delimiter;

				string style = "";
				if(!Globals.IsNullorEmpty(cssClass[i]))
					style = string.Concat("class=", cssClass[i]); 
				
				template.Text += String.Format(@"<a href='{0}' {1}>{2}</a>", href[i], style, label[i]);
			}

			Grid.ClientTemplates.Add(template);
			AttachGridColumnClientTemplate(dataFieldToAttach, template);
		}

		/// <summary>
		/// Attaches a new ClientTemplate to the specified Grid Column
		/// </summary>
		/// <param name="DataFieldName"></param>
		/// <param name="template"></param>
		/// <returns>A reference to the grid column the template was attached to, or null if the template was not found</returns>
		protected virtual CA.GridColumn AttachGridColumnClientTemplate(string DataFieldName, CA.ClientTemplate template)
		{
			foreach(CA.GridColumn gc in Grid.Levels[0].Columns)
			{
				if(gc.DataField == DataFieldName  && gc.Visible)
				{
					gc.DataCellClientTemplateId = template.ID;
					return gc;
				}
			}
			return null;
		}

		/// <summary>
		/// Builds the standard pager slider template and attaches it to the Grid
		/// </summary>
		/// <param name="TitleDataField">The main title to show in the pager</param>
		protected virtual void AddGridPagerTemplate(string TitleDataField)
		{
			AddGridPagerTemplate(TitleDataField, null, null, null, null);
		}

		/// <summary>
		/// Builds the standard pager slider template and attaches it to the Grid
		/// </summary>
		/// <param name="TitleDataField">The main title to show in the pager</param>
		/// <param name="BoolDataField">Makes a red or green flag or the right based on bool</param>
		protected virtual void AddGridPagerTemplate(string TitleDataField, string BoolDataField)
		{
			AddGridPagerTemplate(TitleDataField, null, null, BoolDataField, null);
		}

		/// <summary>
		/// Builds the standard pager slider template and attaches it to the Grid
		/// </summary>
		/// <param name="TitleDataField">The main title to show in the pager</param>
		/// <param name="UserDataField"></param>
		/// <param name="BoolDataField">Makes a red or green flag or the right based on bool</param>
		protected virtual void AddGridPagerTemplate(string TitleDataField, string UserDataField, string BoolDataField)
		{
			AddGridPagerTemplate(TitleDataField, UserDataField, null, BoolDataField, null);
		}

		/// <summary>
		/// Builds the standard pager slider template and attaches it to the Grid
		/// </summary>
		/// <param name="TitleDataField">The main title to show in the pager</param>
		/// <param name="UserDataField"></param>
		/// <param name="DateDataField"></param>
		/// <param name="BoolDataField">Makes a red or green flag or the right based on bool</param>
		protected virtual void AddGridPagerTemplate(string TitleDataField, string UserDataField, string DateDataField, string BoolDataField)
		{
			AddGridPagerTemplate(TitleDataField, UserDataField, DateDataField, BoolDataField, null);
		}
		
		/// <summary>
		/// Builds the standard pager slider template and attaches it to the Grid
		/// </summary>
		/// <param name="TitleDataField">The main title to show in the pager</param>
		/// <param name="UserDataField">Can Be Null</param>
		/// <param name="DateDataField">Can Be Null</param>
		/// <param name="BoolDataField">Makes a red or green flag or the right based on bool, Can Be Null</param>
		/// <param name="ImageSource">Image to show on the left, Can Be Null</param>
		protected virtual void AddGridPagerTemplate(string TitleDataField, string UserDataField, string DateDataField,string BoolDataField, string ImageSource)
		{
			CA.ClientTemplate sliderTemplate = new CA.ClientTemplate();
			sliderTemplate.ID = "SliderTemplate";

			StringBuilder s = new StringBuilder() ;
			s.Append(@"<table class=""GraySliderPopup"" cellspacing=""0"" cellpadding=""0"" border=""0"">
						<tr>
						<td valign=""top"" style=""padding:5px;"">
						<table width=""100%"" cellspacing=""0"" cellpadding=""0"" border=""0"">
						<tr>
							<td width=""25"" align=""center"" valign=""top"" style=""padding-top:3px;"">");
			
			//Attach the left image (ImageSource) if supplied
			if(Globals.IsNullorEmpty(ImageSource))
				s.Append("&nbsp;");
			else
				s.AppendFormat(@"<img src='## DataItem.GetMember(""{0}"").Value ##'  width=""25"" />",ImageSource);
 
			s.Append(@" </td>
						<td>
							<table cellspacing=""0"" cellpadding=""2"" border=""0"" style=""width:255px;"">
							<tr>");


			s.Append(@"<td><table width=""100%"" cellspacing=""0"" cellpadding=""1"" border=""0"">
                <tr>");
 
			// Attach the UserDataField if Present
			if(Globals.IsNullorEmpty(UserDataField))
				s.Append(@"<td class=""CellText"" align=""right"">&nbsp;</td>");
			else
				s.AppendFormat(@"<td class=""CellText"" align=""right"">## DataItem.GetMember(""{0}"").Value ##</td>",UserDataField);

			s.Append(@"</tr><tr>");
             
			// Attach the DateDataField if Present
			if(Globals.IsNullorEmpty(DateDataField))
				s.Append(@"<td class=""CellText"" align=""right"">&nbsp;</td>");
			else
				s.AppendFormat(@"<td class=""CellText"" align=""right""><font color=""#595959"">## DataItem.GetMember(""{0}"").Value ##</font></td>",DateDataField);
			s.Append(@"</tr></table></td>");

			s.Append(@"</tr>
							<tr>
							<td colspan=""2"">
							<table cellspacing=""0"" cellpadding=""0"" border=""0"" width=""100%"">
							<tr>");

			//Attach the TitleDataField
			s.AppendFormat(@"<td width=""230"" colspan=""2"" style=""font-family:verdana;font-size:11px;font-weight:bold;""><div style=""text-overflow:ellipsis;overflow:hidden;width:250px;""><nobr>## DataItem.GetMember(""{0}"").Value ##</nobr></div></td>", TitleDataField);
			
			s.Append(@"</tr>
							</table>                                    
							</tr>
							</table>    
							</td>
						</tr>
						</table>  
						</td>");
			
			//Attach the BoolDataField for the flag image
			if(Globals.IsNullorEmpty(BoolDataField))
				s.Append(@"<td style=""background-color:#CAC6D4;padding:2px;"" align=""center"">&nbsp;</td>");
			else
				s.AppendFormat(@"<td style=""background-color:#CAC6D4;padding:2px;"" align=""center""><img src=""{0}images/## DataItem.GetMember(""{1}"").Value ##.gif"" width=""12"" height=""12"" border=""0""></td>", SiteUrls.Instance().Locations["ControlPanel"], BoolDataField);
			
			s.AppendFormat(@"</tr>
						<tr>
						<td colspan=""2"" style=""height:14px;background-color:#AABBDD;"">
						<table width=""100%"" cellspacing=""0"" cellpadding=""0"" border=""0"">
						<tr>
							<td style=""padding-left:5px;color:white;font-family:verdana;font-size:10px;"">
							{1} <b>## DataItem.PageIndex + 1 ##</b> {2} <b>## {0}.PageCount ##</b>
							</td>
							<td style=""padding-right:5px;color:white;font-family:verdana;font-size:10px;"" align=""right"">
							{3} <b>## DataItem.Index + 1 ##</b> {2} <b>## {0}.RecordCount ##</b>
							</td>
						</tr>
						</table>  
						</td>
						</tr>
						</table>", Grid.ClientID, ResourceManager.GetString("CP_GridPager_Page") , ResourceManager.GetString("CP_GridPager_Of") , ResourceManager.GetString("CP_GridPager_Item") );

			//Add the slider template
			sliderTemplate.Text = s.ToString(); 
			Grid.ClientTemplates.Add(sliderTemplate);
			Grid.SliderPopupClientTemplateId = sliderTemplate.ID;
			
			//Configure the SliderTemplate and Grid
			Grid.PagerStyle = CA.GridPagerStyle.Slider;
			Grid.SliderHeight=20;
			Grid.SliderWidth=150 ;
			Grid.SliderGripWidth=9 ;
			Grid.SliderPopupOffsetX=20 ;
		}

		/// <summary>
		/// Apply any user settings to the page, this method is usually called after the datasource is
		/// set on the grid in the buildGrid()
		/// </summary>
		protected virtual void ApplyUserSettings()
		{
	
			Grid.ShowHeader = this.ShowHeading;
			Grid.PreExpandOnGroup = this.ExpandGrouping;
			Grid.ShowSearchBox = this.EnableSearchBox;
			if(!this.EnableGrouping || Grid.GroupBy.Length > 0 )
			{
				//This code along with no GroupBy is required to show the header but disable grouping
				Grid.GroupByCssClass = "disabled";
				Grid.GroupByTextCssClass = "disabled";
				Grid.GroupingNotificationTextCssClass = "disabled";
				Grid.Levels[0].AllowGrouping = false;
			}
			else
			{
				Grid.TreeLineImagesFolderUrl= string.Format("{0}images/caimages/lines",  SiteUrls.Instance().Locations["ControlPanel"]); 
				Grid.TreeLineImageWidth=21; 
				Grid.TreeLineImageHeight=19; 
				Grid.IndentCellWidth=22; 
				Grid.GroupByCssClass="GroupByCell"; 
				Grid.GroupByTextCssClass="GroupByText"; 
				Grid.GroupingNotificationTextCssClass="GridHeaderText"; 
				Grid.GroupBySortAscendingImageUrl="group_asc.gif"; 
				Grid.GroupBySortDescendingImageUrl="group_desc.gif"; 
				Grid.GroupBySortImageWidth=10; 
				Grid.GroupBySortImageHeight=10; 
				Grid.Levels[0].AllowGrouping = true;
				Grid.GroupingPageSize=5;
			}

			//Note you must manually set the Grid Recordcount when assigning the DataSource
			if(!this.ShowScrollBar)
				Grid.ShowFooter = (Grid.PageCount > 1);
			
			Grid.Levels[0].AllowReordering = false;

		}

		#endregion

	}
}
